<!doctype html>
<html>

<head>
    <meta charset="utf-8" />
    <title>Generate Mozilla Security Recommended Web Server Configuration Files</title>
    <link rel="stylesheet" href="../css/screen.css" />
    <link rel="stylesheet" href="https://mozorg.cdn.mozilla.net/media/css/tabzilla-min.css" />
    <style>
        div#server-config-text pre {
            background-color: #F7F7F7;
            border-radius: 3px;
            padding: 2em;
        }
        label, p {
            font-family: 'Open Sans', "Lucida Sans", "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
            font-weight: normal;
            text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.75);
        }
        .message {
            font-size: 150%;
        }
        pre {
            overflow-x: auto;
        }

    </style>
    <link rel="shortcut icon" href="../favicon.ico">

    <script src="https://cdn.bootcss.com/jquery/2.2.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js"></script>
    <script src="https://mozorg.cdn.mozilla.net/en-US/tabzilla/tabzilla.js"></script>
    <link rel="stylesheet" href="https://cdn.bootcss.com/jqueryui/1.11.4/jquery-ui.theme.css">
    <script src="https://cdn.bootcss.com/jqueryui/1.11.4/jquery-ui.js"></script>
    <script>
        // https://gist.github.com/cowboy/566233
        var isSemVer=(function(){var a=/^(<|>|[=!<>]=)?\s*(\d+(?:\.\d+){0,2})([a-z][a-z0-9\-]*)?$/i;function b(e,c){var d=(e+"").match(a);return d?(c?(d[1]||"=="):"")+'"'+(d[2]+".0.0").match(/\d+(?:\.\d+){0,2}/)[0].replace(/(?:^|\.)(\d+)/g,function(g,f){return Array(9-f.length).join(0)+f;})+(d[3]||"~")+'"':(c?"==0":1);}return function(e){e=b(e);for(var c,d=1;c=arguments[d++];){if(!(new Function("return "+e+b(c,1)))()){return false;}}return true;};})();
        // isSemVer says "1.0.1 > 1.0.1e" and isOpenSSLSemVer says "1.0.1 < 1.0.1e". isOpenSSLSemVer is needed to accommodate OpenSSL's version grammar
        var isOpenSSLSemVer=(function(){var a=/^(<|>|[=!<>]=)?\s*(\d+(?:\.\d+){0,2})([a-z][a-z0-9\-]*)?$/i;function b(e,c){var d=(e+"").match(a);return d?(c?(d[1]||"=="):"")+'"'+(d[2]+".0.0").match(/\d+(?:\.\d+){0,2}/)[0].replace(/(?:^|\.)(\d+)/g,function(g,f){return Array(9-f.length).join(0)+f;})+(d[3]||"")+'"':(c?"==0":1);}return function(e){e=b(e);for(var c,d=1;c=arguments[d++];){if(!(new Function("return "+e+b(c,1)))()){return false;}}return true;};})();
    </script>
    <!-- <script>
        if (location.protocol != "https:")
            location.protocol = "http:";
    </script> -->

    <script id="nginx-template" type="text/x-handlebars-template">
<h2>{{server}} {{serverVersion}} | {{securityProfile}} profile | OpenSSL {{opensslVersion}} | <a href="?{{queryString}}">link</a></h2>
<p>Oldest compatible clients: {{clientList}}</p>
<pre>
{{#if hstsEnabled}}
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    return 301 https://$host$request_uri;
}

{{/if}}
server {
{{listen}}

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /path/to/signed_cert_plus_intermediates;
    ssl_certificate_key /path/to/private_key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
{{sslSessionTickets}}
{{dhparam}}

    # {{securityProfile}} configuration. tweak to your needs.
    ssl_protocols {{sslProtocols}};
    ssl_ciphers '{{cipherSuites}}';
    ssl_prefer_server_ciphers on;
{{hsts}}
{{ocspstapling}}

    resolver &lt;IP DNS resolver&gt;;

    ....
}
</pre>
    </script>

    <script id="apache-template" type="text/x-handlebars-template">
<h2>{{server}} {{serverVersion}} | {{securityProfile}} profile | OpenSSL {{opensslVersion}} | <a href="?{{queryString}}">link</a></h2>
<p>Oldest compatible clients: {{clientList}}</p>
<pre>
&lt;VirtualHost *:443&gt;
    ...
    SSLEngine on
{{certFile}}
    SSLCertificateKeyFile   /path/to/private/key

    # Uncomment the following directive when using client certificate authentication
    #SSLCACertificateFile    /path/to/ca_certs_for_client_authentication

{{hsts}}
    ...
&lt;/VirtualHost&gt;

# {{securityProfile}} configuration, tweak to your needs
SSLProtocol             {{sslProtocols}}
SSLCipherSuite          {{cipherSuites}}
SSLHonorCipherOrder     on
{{compression}}
{{sslSessionTickets}}
{{ocspStapling}}
{{ocspStaplingCache}}
</pre>
    </script>

    <script id="haproxy-template" type="text/x-handlebars-template">
<h2>{{server}} {{serverVersion}} | {{securityProfile}} profile | OpenSSL {{opensslVersion}} | <a href="?{{queryString}}">link</a></h2>
<p>Oldest compatible clients: {{clientList}}</p>
<span class="message">{{message}}</span>
<pre style="visibility: {{visibility}};">
global
    # set default parameters to the {{securityProfile}} configuration
    {{#if dhparam}}tune.ssl.default-dh-param {{maxDHKeySize}}{{/if}}
    ssl-default-bind-ciphers {{cipherSuites}}
    ssl-default-bind-options {{sslProtocols}} no-tls-tickets
    ssl-default-server-ciphers {{cipherSuites}}
    ssl-default-server-options {{sslProtocols}} no-tls-tickets

frontend ft_test
    mode    http
    bind    :443 ssl crt /path/to/&lt;cert+privkey+intermediate+dhparam&gt;
    bind    :80
    redirect scheme https code 301 if !{ ssl_fc }
{{hsts}}
</pre>
    </script>

    <script id="elb-template" type="text/x-handlebars-template">
<h2>{{server}} {{serverVersion}} | {{securityProfile}} profile | OpenSSL {{opensslVersion}} | <a href="?{{queryString}}">link</a></h2>
<p>Oldest compatible clients: {{clientList}}</p>
<span class="message">{{message}}</span>
<p>This <a href="https://aws.amazon.com/cloudformation/">Amazon Web Services CloudFormation</a> template
  will create an <a href="https://aws.amazon.com/elasticloadbalancing/">Elastic Load Balancer</a> which
  terminates HTTPS connections using the Mozilla recommended ciphersuites and protocols.
</p>
<pre style="visibility: {{visibility}};">
{{elbJson}}
</pre>
    </script>

    <script id="lighttpd-template" type="text/x-handlebars-template">
<h2>{{server}} {{serverVersion}} | {{securityProfile}} profile | OpenSSL {{opensslVersion}} | <a href="?{{queryString}}">link</a></h2>
<p>Oldest compatible clients : {{clientList}}</p>
<pre>
$SERVER["socket"] == ":443" {
    protocol     = "https://"
    ssl.engine   = "enable"
    ssl.disable-client-renegotiation = "enable"

    # pemfile is cert+privkey, ca-file is the intermediate chain in one file
    ssl.pemfile               = "/path/to/signed_cert_plus_private_key.pem"
    ssl.ca-file               = "/path/to/intermediate_certificate.pem"
    {{dhparam}}
    # ECDH/ECDHE ciphers curve strength (see `openssl ecparam -list_curves`)
    ssl.ec-curve              = "secp384r1"
    # Compression is by default off at compile-time, but use if needed
    # ssl.use-compression     = "disable"

    # Environment flag for HTTPS enabled
    setenv.add-environment = (
        "HTTPS" => "on"
    )

    # {{securityProfile}} configuration, tweak to your needs
{{sslProtocols}}
    ssl.honor-cipher-order    = "enable"
    ssl.cipher-list           = "{{cipherSuites}}"
{{hsts}}

    ...
}
</pre>
    </script>

    <script>
        var profiles = {
            modern: {
                cipherSuites: 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256',
                elbPolicy: [
                    "Protocol-TLSv1.2",
                    "Server-Defined-Cipher-Order",
                    "ECDHE-ECDSA-AES128-GCM-SHA256",
                    "ECDHE-RSA-AES128-GCM-SHA256",
                    "ECDHE-ECDSA-AES128-SHA256",
                    "ECDHE-RSA-AES128-SHA256",
                    "ECDHE-ECDSA-AES256-GCM-SHA384",
                    "ECDHE-RSA-AES256-GCM-SHA384",
                    "ECDHE-ECDSA-AES256-SHA384",
                    "ECDHE-RSA-AES256-SHA384",
                ],
                sslProtocols: {
                    apache: 'all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1',
                    nginx: 'TLSv1.2',
                    haproxy: 'no-sslv3 no-tlsv10 no-tlsv11',
                    lighttpd: '    ssl.use-sslv2 = "disable"\n    ssl.use-sslv3 = "disable"'
                },
                clientList: 'Firefox 27, Chrome 30, IE 11 on Windows 7, Edge, Opera 17, Safari 9, Android 5.0, and Java 8',
                maxDHKeySize: '2048',
                messages: []
            },
            intermediate: {
                cipherSuites: 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS',
                elbPolicy: [
                    "Protocol-TLSv1",
                    "Protocol-TLSv1.1",
                    "Protocol-TLSv1.2",
                    "Server-Defined-Cipher-Order",
                    "ECDHE-ECDSA-CHACHA20-POLY1305",
                    "ECDHE-RSA-CHACHA20-POLY1305",
                    "ECDHE-ECDSA-AES128-GCM-SHA256",
                    "ECDHE-RSA-AES128-GCM-SHA256",
                    "ECDHE-ECDSA-AES256-GCM-SHA384",
                    "ECDHE-RSA-AES256-GCM-SHA384",
                    "DHE-RSA-AES128-GCM-SHA256",
                    "DHE-RSA-AES256-GCM-SHA384",
                    "ECDHE-ECDSA-AES128-SHA256",
                    "ECDHE-RSA-AES128-SHA256",
                    "ECDHE-ECDSA-AES128-SHA",
                    "ECDHE-RSA-AES256-SHA384",
                    "ECDHE-RSA-AES128-SHA",
                    "ECDHE-ECDSA-AES256-SHA384",
                    "ECDHE-ECDSA-AES256-SHA",
                    "ECDHE-RSA-AES256-SHA",
                    "DHE-RSA-AES128-SHA256",
                    "DHE-RSA-AES128-SHA",
                    "DHE-RSA-AES256-SHA256",
                    "DHE-RSA-AES256-SHA",
                    "ECDHE-ECDSA-DES-CBC3-SHA",
                    "ECDHE-RSA-DES-CBC3-SHA",
                    "EDH-RSA-DES-CBC3-SHA",
                    "AES128-GCM-SHA256",
                    "AES256-GCM-SHA384",
                    "AES128-SHA256",
                    "AES256-SHA256",
                    "AES128-SHA",
                    "AES256-SHA",
                    "DES-CBC3-SHA",
                ],
                sslProtocols: {
                    apache: 'all -SSLv2 -SSLv3',
                    nginx: 'TLSv1 TLSv1.1 TLSv1.2',
                    haproxy: 'no-sslv3',
                    lighttpd: '    ssl.use-sslv2 = "disable"\n    ssl.use-sslv3 = "disable"'
                },
                clientList: 'Firefox 1, Chrome 1, IE 7, Opera 5, Safari 1, Windows XP IE8, Android 2.3, Java 7',
                maxDHKeySize: '2048',
                messages: []
            },
            old: {
                cipherSuites: 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP',
                elbPolicy: [
                    "Protocol-SSLv3",
                    "Protocol-TLSv1",
                    "Protocol-TLSv1.1",
                    "Protocol-TLSv1.2",
                    "Server-Defined-Cipher-Order",
                    "ECDHE-ECDSA-AES128-GCM-SHA256",
                    "ECDHE-RSA-AES128-GCM-SHA256",
                    "ECDHE-ECDSA-AES128-SHA256",
                    "ECDHE-RSA-AES128-SHA256",
                    "ECDHE-ECDSA-AES128-SHA",
                    "ECDHE-RSA-AES128-SHA",
                    "DHE-RSA-AES128-SHA",
                    "ECDHE-ECDSA-AES256-GCM-SHA384",
                    "ECDHE-RSA-AES256-GCM-SHA384",
                    "ECDHE-ECDSA-AES256-SHA384",
                    "ECDHE-RSA-AES256-SHA384",
                    "ECDHE-RSA-AES256-SHA",
                    "ECDHE-ECDSA-AES256-SHA",
                    "AES128-GCM-SHA256",
                    "AES128-SHA256",
                    "AES128-SHA",
                    "AES256-GCM-SHA384",
                    "AES256-SHA256",
                    "AES256-SHA",
                    "DES-CBC3-SHA",
                    "DHE-RSA-AES256-SHA256",
                    "DHE-RSA-AES256-SHA",
                    "DHE-DSS-AES256-SHA",
                    "DHE-DSS-AES128-GCM-SHA256",
                    "DHE-RSA-AES128-GCM-SHA256",
                    "DHE-RSA-AES128-SHA256",
                    "DHE-DSS-AES128-SHA256"
                ],
                sslProtocols: {
                    apache: 'all -SSLv2',
                    nginx: 'SSLv3 TLSv1 TLSv1.1 TLSv1.2',
                    lighttpd: 'SSLv3 TLSv1 TLSv1.1 TLSv1.2',
                    haproxy: '',
                    lighttpd: '    ssl.use-sslv2 = "disable"\n    ssl.use-sslv3 = "enable"'
                },
                clientList: 'Windows XP IE6, Java 6',
                maxDHKeySize: '1024',
                messages: []
            }
        };

        var versions = {
            apache: ["1.3","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.0.6","2.0.7","2.0.8","2.0.9","2.0.10","2.0.11","2.0.12","2.0.13","2.0.14","2.0.15","2.0.16","2.0.17","2.0.18","2.0.19","2.0.20","2.0.21","2.0.22","2.0.23","2.0.24","2.0.25","2.0.26","2.0.27","2.0.28","2.0.29","2.0.30","2.0.31","2.0.32","2.0.33","2.0.34","2.0.35","2.0.36","2.0.37","2.0.38","2.0.39","2.0.40","2.0.41","2.0.42","2.0.43","2.0.44","2.0.45","2.0.46","2.0.47","2.0.48","2.0.49","2.0.50","2.0.51","2.0.52","2.0.53","2.0.54","2.0.55","2.0.56","2.0.57","2.0.58","2.0.59","2.0.60","2.0.61","2.0.62","2.0.63","2.0.64","2.0.65","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.1.10","2.2.0","2.2.1","2.2.2","2.2.3","2.2.4","2.2.5","2.2.6","2.2.7","2.2.8","2.2.9","2.2.10","2.2.11","2.2.12","2.2.13","2.2.14","2.2.15","2.2.16","2.2.17","2.2.18","2.2.19","2.2.20","2.2.21","2.2.22","2.2.23","2.2.24","2.2.25","2.2.26","2.2.27","2.2.28","2.2.29","2.2.30","2.2.31","2.2.32","2.2.34","2.3.0","2.3.1","2.3.2","2.3.3","2.3.4","2.3.5","2.3.6","2.3.7","2.3.8","2.3.9","2.3.10","2.3.11","2.3.12","2.3.13","2.3.14","2.3.15","2.3.16","2.4.0","2.4.1","2.4.2","2.4.3","2.4.4","2.4.5","2.4.6","2.4.7","2.4.8","2.4.9","2.4.10","2.4.11","2.4.12","2.4.13","2.4.14","2.4.15","2.4.16","2.4.17","2.4.18","2.4.20","2.4.23","2.4.25","2.4.26","2.4.27","2.4.28"],
            nginx: ["0.1.0","0.1.1","0.1.2","0.1.3","0.1.4","0.1.5","0.1.6","0.1.7","0.1.8","0.1.9","0.1.10","0.1.11","0.1.12","0.1.13","0.1.14","0.1.15","0.1.16","0.1.17","0.1.18","0.1.19","0.1.20","0.1.21","0.1.22","0.1.23","0.1.24","0.1.25","0.1.26","0.1.27","0.1.28","0.1.29","0.1.30","0.1.31","0.1.32","0.1.33","0.1.34","0.1.35","0.1.36","0.1.37","0.1.38","0.1.39","0.1.40","0.1.41","0.1.42","0.1.43","0.1.44","0.1.45","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.3.0","0.3.1","0.3.2","0.3.3","0.3.4","0.3.5","0.3.6","0.3.7","0.3.8","0.3.9","0.3.10","0.3.11","0.3.12","0.3.13","0.3.14","0.3.15","0.3.16","0.3.17","0.3.18","0.3.19","0.3.20","0.3.21","0.3.22","0.3.23","0.3.24","0.3.25","0.3.26","0.3.27","0.3.28","0.3.29","0.3.30","0.3.31","0.3.32","0.3.33","0.3.34","0.3.35","0.3.36","0.3.37","0.3.38","0.3.39","0.3.40","0.3.41","0.3.42","0.3.43","0.3.44","0.3.45","0.3.46","0.3.47","0.3.48","0.3.49","0.3.50","0.3.51","0.3.52","0.3.53","0.3.54","0.3.55","0.3.56","0.3.57","0.3.58","0.3.59","0.3.60","0.3.61","0.4.0","0.4.1","0.4.2","0.4.3","0.4.4","0.4.5","0.4.6","0.4.7","0.4.8","0.4.9","0.4.10","0.4.11","0.4.12","0.4.13","0.4.14","0.5.0","0.5.1","0.5.2","0.5.3","0.5.4","0.5.5","0.5.6","0.5.7","0.5.8","0.5.9","0.5.10","0.5.11","0.5.12","0.5.13","0.5.14","0.5.15","0.5.16","0.5.17","0.5.18","0.5.19","0.5.20","0.5.21","0.5.22","0.5.23","0.5.24","0.5.25","0.5.26","0.5.27","0.5.28","0.5.29","0.5.30","0.5.31","0.5.32","0.5.33","0.5.34","0.5.35","0.5.36","0.5.37","0.5.38","0.6.0","0.6.1","0.6.2","0.6.3","0.6.4","0.6.5","0.6.6","0.6.7","0.6.8","0.6.9","0.6.10","0.6.11","0.6.12","0.6.13","0.6.14","0.6.15","0.6.16","0.6.17","0.6.18","0.6.19","0.6.20","0.6.21","0.6.22","0.6.23","0.6.24","0.6.25","0.6.26","0.6.27","0.6.28","0.6.29","0.6.30","0.6.31","0.6.32","0.6.33","0.6.34","0.6.35","0.6.36","0.6.37","0.6.38","0.6.39","0.7.0","0.7.1","0.7.2","0.7.3","0.7.4","0.7.5","0.7.6","0.7.7","0.7.8","0.7.9","0.7.10","0.7.11","0.7.12","0.7.13","0.7.14","0.7.15","0.7.16","0.7.17","0.7.18","0.7.19","0.7.20","0.7.21","0.7.22","0.7.23","0.7.24","0.7.25","0.7.26","0.7.27","0.7.28","0.7.29","0.7.30","0.7.31","0.7.32","0.7.33","0.7.34","0.7.35","0.7.36","0.7.37","0.7.38","0.7.39","0.7.40","0.7.41","0.7.42","0.7.43","0.7.44","0.7.45","0.7.46","0.7.47","0.7.48","0.7.49","0.7.50","0.7.51","0.7.52","0.7.53","0.7.54","0.7.55","0.7.56","0.7.57","0.7.58","0.7.59","0.7.60","0.7.61","0.7.62","0.7.63","0.7.64","0.7.65","0.7.66","0.7.67","0.7.68","0.7.69","0.8.0","0.8.1","0.8.2","0.8.3","0.8.4","0.8.5","0.8.6","0.8.7","0.8.8","0.8.9","0.8.10","0.8.11","0.8.12","0.8.13","0.8.14","0.8.15","0.8.16","0.8.17","0.8.18","0.8.19","0.8.20","0.8.21","0.8.22","0.8.23","0.8.24","0.8.25","0.8.26","0.8.27","0.8.28","0.8.29","0.8.30","0.8.31","0.8.32","0.8.33","0.8.34","0.8.35","0.8.36","0.8.37","0.8.38","0.8.39","0.8.40","0.8.41","0.8.42","0.8.43","0.8.44","0.8.45","0.8.46","0.8.47","0.8.48","0.8.49","0.8.50","0.8.51","0.8.52","0.8.53","0.8.54","0.8.55","0.9.0","0.9.1","0.9.2","0.9.3","0.9.4","0.9.5","0.9.6","0.9.7","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.0.5","1.0.6","1.0.7","1.0.8","1.0.9","1.0.10","1.0.11","1.0.12","1.0.13","1.0.14","1.0.15","1.1.0","1.1.1","1.1.2","1.1.3","1.1.4","1.1.5","1.1.6","1.1.7","1.1.8","1.1.9","1.1.10","1.1.11","1.1.12","1.1.13","1.1.14","1.1.15","1.1.16","1.1.17","1.1.18","1.1.19","1.2.0","1.2.1","1.2.2","1.2.3","1.2.4","1.2.5","1.2.6","1.2.7","1.2.8","1.2.9","1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.3.6","1.3.7","1.3.8","1.3.9","1.3.10","1.3.11","1.3.12","1.3.13","1.3.14","1.3.15","1.3.16","1.4.0","1.4.1","1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.5.0","1.5.1","1.5.2","1.5.3","1.5.4","1.5.5","1.5.6","1.5.7","1.5.8","1.5.9","1.5.10","1.5.11","1.5.12","1.5.13","1.6.0","1.6.1","1.6.2","1.6.3","1.7.0","1.7.1","1.7.2","1.7.3","1.7.4","1.7.5","1.7.6","1.7.7","1.7.8","1.7.9","1.7.10","1.7.11","1.7.12","1.8.0","1.8.1","1.9.0","1.9.1","1.9.2","1.9.3","1.9.4","1.9.5","1.9.6","1.9.7","1.9.8","1.9.9","1.9.10","1.9.11","1.9.12","1.9.13","1.9.14","1.9.15","1.10.0","1.10.1","1.10.2","1.10.3"],
            lighttpd: ["1.4.29","1.4.30","1.4.31","1.4.32","1.4.33","1.4.34","1.4.35","1.4.36","1.4.37","1.4.38","1.4.39","1.4.40","1.4.41","1.4.42"],
            haproxy: ["1.0.0","1.0.1","1.0.2","1.1.0","1.1.1","1.1.2","1.1.3","1.1.4","1.1.5","1.1.6","1.1.7","1.1.8","1.1.9","1.1.10","1.1.11","1.1.12","1.1.13","1.1.14","1.1.15","1.1.16","1.1.17","1.1.18","1.1.19","1.1.20","1.1.21","1.1.22","1.1.23","1.1.24","1.1.25","1.1.26","1.1.27","1.2.0","1.2.1","1.2.2","1.2.3-pre1","1.2.3","1.2.4","1.2.5-pre1","1.2.5-pre2","1.2.5-pre3","1.2.5-pre4","1.2.5","1.2.5.1","1.2.5.2","1.2.6-pre1","1.2.6-pre2","1.2.6-pre3","1.2.6-pre4","1.2.6-pre5","1.2.6","1.2.7rc","1.2.7","1.2.7.1","1.2.8","1.2.9","1.2.10","1.2.10.1","1.2.11","1.2.11.1","1.2.12","1.2.13","1.2.13.1","1.2.14","1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.3.6","1.3.6.1","1.3.7","1.3.8","1.3.8.1","1.3.8.2","1.3.9","1.3.10","1.3.10.1","1.3.10.2","1.3.11","1.3.11.1","1.3.11.2","1.3.11.3","1.3.11.4","1.3.12","1.3.12.1","1.3.12.2","1.3.12.3","1.3.13","1.3.14","1.3.15","1.3.16-rc1","1.3.16-rc2","1.3.16","1.3.17","1.3.18","1.4-dev0","1.4-dev1","1.4-dev2","1.4-dev3","1.4-dev4","1.4-dev5","1.4-dev6","1.4-dev7","1.4-dev8","1.4-rc1","1.4.0","1.4.1","1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.4.8","1.4.9","1.4.10","1.4.11","1.4.12","1.4.13","1.4.14","1.4.15","1.4.16","1.4.17","1.4.18","1.4.19","1.4.20","1.4.21","1.4.22","1.4.23","1.4.24","1.4.25","1.4.26","1.5-dev1","1.5-dev2","1.5-dev3","1.5-dev4","1.5-dev5","1.5-dev6","1.5-dev7","1.5-dev8","1.5-dev9","1.5-dev10","1.5-dev11","1.5-dev12","1.5-dev13","1.5-dev14","1.5-dev15","1.5-dev16","1.5-dev17","1.5-dev18","1.5-dev19","1.5-dev20","1.5-dev21","1.5-dev22","1.5-dev23","1.5-dev24","1.5-dev25","1.5-dev26","1.5.0","1.5.1","1.5.2","1.5.3","1.5.4","1.5.5","1.5.6","1.5.7","1.5.8","1.5.9","1.5.10","1.5.11","1.5.12","1.5.13","1.5.14","1.5.15","1.5.16","1.5.17","1.5.18","1.5.19","1.6.0","1.6.1","1.6.2","1.6.3","1.6.4","1.6.5","1.6.6","1.6.7","1.6.8","1.6.9","1.6.10","1.6.11","1.6.12","1.6.13","1.7.0","1.7.1","1.7.2","1.7.3","1.7.4","1.7.5","1.7.6","1.7.7","1.7.8","1.7.9"],
            openssl:["0.9.0b","0.9.1b","0.9.1c","0.9.2b","0.9.3","0.9.3a","0.9.4","0.9.5","0.9.5a","0.9.6","0.9.6a","0.9.6b","0.9.6c","0.9.6d","0.9.6e","0.9.6f","0.9.6g","0.9.6h","0.9.6i","0.9.6j","0.9.6k","0.9.6l","0.9.6h","0.9.7","0.9.7a","0.9.7b","0.9.7c","0.9.7d","0.9.7e","0.9.7f","0.9.7g","0.9.7h","0.9.7i","0.9.7j","0.9.7k","0.9.7l","0.9.7h","0.9.8","0.9.8a","0.9.8b","0.9.8c","0.9.8d","0.9.8e","0.9.8f","0.9.8g","0.9.8h","0.9.8i","0.9.8j","0.9.8k","0.9.8l","0.9.8m","0.9.8n","0.9.8o","0.9.8p","0.9.8q","0.9.8r","0.9.8s","0.9.8t","0.9.8u","0.9.8v","0.9.8w","0.9.8x","0.9.8y","0.9.8z","0.9.8za","0.9.8zb","0.9.8zc","0.9.8zd","0.9.8ze","0.9.8zf","0.9.8zg","1.0.0","1.0.0a","1.0.0b","1.0.0c","1.0.0d","1.0.0e","1.0.0f","1.0.0g","1.0.0h","1.0.0i","1.0.0j","1.0.0k","1.0.0l","1.0.0m","1.0.0n","1.0.0o","1.0.0p","1.0.0q","1.0.0r","1.0.0s","1.0.1","1.0.1a","1.0.1b","1.0.1c","1.0.1d","1.0.1e","1.0.1f","1.0.1g","1.0.1h","1.0.1i","1.0.1j","1.0.1k","1.0.1l","1.0.1m","1.0.1n","1.0.1o","1.0.1p","1.0.1q","1.0.1r","1.0.1s","1.0.1t","1.0.1u","1.0.2","1.0.2a","1.0.2b","1.0.2c","1.0.2d","1.0.2e","1.0.2f","1.0.2g","1.0.2h","1.0.2i","1.0.2j","1.0.2k","1.0.2l","1.1.0a","1.1.0b","1.1.0c","1.1.0d","1.1.0e"]
        };

        var messageTypes = {
            oldOpenSSL: 'TLS v1.1 and v1.2 support is only present in OpenSSL 1.0.1 and newer',
            oldApache: 'TLS v1.1 and v1.2 support is only present in Apache 2.2.23 and newer'
        };

        $(function() {
            $( document ).tooltip();
        });

        function getVersionConstrainedDirectives(data) {
            switch (data.server) {
                case "nginx":
                    // http://nginx.org/en/docs/http/ngx_http_core_module.html
                    if (isSemVer(data.serverVersion, ">=0.7.2")) {
                        data.dhparam = '\n    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits' + '\n' +
                            '    ssl_dhparam /path/to/dhparam.pem;';
                    }
                    if (isSemVer(data.serverVersion, ">=1.3.7")) {
                        data.ocspstapling = '\n    # OCSP Stapling ---' + '\n' +
                            '    # fetch OCSP records from URL in ssl_certificate and cache them' + '\n' +
                            '    ssl_stapling on;' + '\n' +
                            '    ssl_stapling_verify on;' + '\n' +
                            '\n' +
                            '    ## verify chain of trust of OCSP response using Root CA and Intermediate certs' + '\n' +
                            '    ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;';
                    }
                    if (data.hstsEnabled == "true") {
                        data.hsts = '\n    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)' + '\n' +
                            '    add_header Strict-Transport-Security max-age=15768000;';
                    }
                    if (isSemVer(data.serverVersion, ">=1.9.5")) {
                        data.listen = '    listen 443 ssl http2;\n' +
                            '    listen [::]:443 ssl http2;';
                    } else if (isSemVer(data.serverVersion, ">=0.7.14")) {
                        data.listen = '    listen 443 ssl;\n' +
                            '    listen [::]:443 ssl;';
                    } else {
                        data.listen = '    listen 443;' + '\n' +
                            '    listen [::]:443;\n' +
                            '    ssl on;';
                    }
                    if (isOpenSSLSemVer(data.opensslVersion, ">=0.9.8f") && isSemVer(data.serverVersion, '>=1.5.9')) {
                        data.sslSessionTickets = '    ssl_session_tickets off;'
                    }
                    break;
                case "apache":
                    // https://httpd.apache.org/docs/current/mod/mod_ssl.html
                    if (isOpenSSLSemVer(data.opensslVersion, ">=0.9.8")) {
                        if ((/^2\.2/.test(data.serverVersion) && isSemVer(data.serverVersion, '>=2.2.24')) || isSemVer(data.serverVersion, '>=2.4.3')) {
                            data.compression = 'SSLCompression          off';
                        }
                    }
                    if (isOpenSSLSemVer(data.opensslVersion, ">=0.9.8h") && isSemVer(data.serverVersion, '>=2.3.3')) {
                        data.ocspStapling = '\n# OCSP Stapling, only in httpd 2.3.3 and later' + '\n' +
                            'SSLUseStapling          on' + '\n' +
                            'SSLStaplingResponderTimeout 5' + '\n' +
                            'SSLStaplingReturnResponderErrors off';
                        data.ocspStaplingCache = 'SSLStaplingCache        shmcb:/var/run/ocsp(128000)' + '\n';

                    }
                    if (isOpenSSLSemVer(data.opensslVersion, ">=0.9.8f")) {
                        if ((/^2\.2/.test(data.serverVersion) && isSemVer(data.serverVersion, '>=2.2.30')) || isSemVer(data.serverVersion, '>=2.4.11')) {
                            data.sslSessionTickets = 'SSLSessionTickets       off';
                        }
                    }
                    if (isSemVer(data.serverVersion, '>=2.4.8')) {
                        data.certFile = '    SSLCertificateFile      /path/to/signed_certificate_followed_by_intermediate_certs';
                    } else {
                        data.certFile = '    SSLCertificateFile      /path/to/signed_certificate\n' +
                            '    SSLCertificateChainFile /path/to/intermediate_certificate';
                    }
                    if (data.hstsEnabled == "true") {
                        data.hsts = '\n    # HSTS (mod_headers is required) (15768000 seconds = 6 months)' + '\n' +
                            '    Header always set Strict-Transport-Security "max-age=15768000"';
                    }
                    if (isSemVer(data.serverVersion, '>=2.3.16')) {
                        data.sslProtocols = data.sslProtocols.replace(' -SSLv2', '');
                    }
                    break;
                case "haproxy":
                    // http://www.haproxy.org/download/1.5/doc/configuration.txt
                    if (data.hstsEnabled == "true") {
                        data.hsts = '\n    # HSTS (15768000 seconds = 6 months)' + '\n' +
                            '    http-response set-header Strict-Transport-Security max-age=15768000';
                    }
                    if (isSemVer(data.serverVersion, "<1.5")) {
                        data.visibility = 'hidden';
                        data.message = "HAProxy didn't support SSL until version 1.5 and newer";
                    }
                    data.dhparam = true
                    break;
                case "lighttpd":
                    // http://redmine.lighttpd.net/projects/1/wiki/docs_ssl
                    if (data.hstsEnabled == "true") {
                        data.hsts = '\n    # HSTS(15768000 seconds = 6 months)\n' +
                            '    setenv.add-response-header  = (\n' +
                            '        "Strict-Transport-Security" => "max-age=15768000;"\n' +
                            '    )';
                    }
                    if (isSemVer(data.serverVersion, ">=1.4.29")) {
                        data.dhparam = '\n    # for DH/DHE ciphers, dhparam should be >= 2048-bit\n' +
                                       '    ssl.dh-file               = "/path/to/dhparam.pem"'
                    }
                    break;
            }
            return data;
        }

        function includesDHEcipherSuites(suites) {
            function isDHE(suite) {
                return /^DHE/.test(suite);
            }
            return suites.split(':').filter(isDHE).length > 0
        }

        $(document).ready(function() {
            function loadFromQueryString() {
                // http://stackoverflow.com/a/10834119/837015
                var defaults = {
                    "server": "apache-2.2.15",
                    "openssl": "1.0.1e",
                    "hsts": "yes",
                    "profile": "intermediate"
                };
                var queries = defaults;
                var search = document.location.search.trim();

                $.each(search.substr(1).split('&'), function(c, q) {
                    var i = q.split('=');
                    queries[i[0].toString()] = i.length == 2 ? i[1].toString() : "true";
                });

                var server = queries["server"].split("-");

                $("#server-version").val(server[1]);
                $("#openssl-version").val(queries["openssl"]);
                $("input#hsts-enabled").attr("checked", queries["hsts"] === "yes");
                $("div#server-list input#" + server[0]).attr("checked", true);
                $("div#security-profile-list input#" + queries["profile"]).attr("checked", true);
            }

            function toggleProfileAvailability(disableProfileTest, currentProfile, targetProfile, message) {
                profileOrder = ["modern", "intermediate", "old"];
                result = currentProfile;
                if (disableProfileTest) {
                    if ($.inArray(message, profiles[targetProfile]["messages"]) == -1) {
                        profiles[targetProfile]["messages"].push(message);
                    }
                    if ($("#security-profile-list input#" + targetProfile).prop("disabled") == false) {
                        $("#security-profile-list input#" + targetProfile).prop("disabled", true);
                        if (currentProfile == targetProfile) {
                            fallbackProfile = profileOrder[(profileOrder.indexOf(targetProfile) + 1 < profileOrder.length ?
                                profileOrder.indexOf(targetProfile) + 1 :
                                0)];
                            $("#security-profile-list input#" + fallbackProfile).prop("checked", true);
                            result = fallbackProfile;
                        }
                    }
                } else {
                    if ($.inArray(message, profiles[targetProfile]["messages"]) != -1) {
                        profiles[targetProfile]["messages"].splice(profiles[targetProfile]["messages"].indexOf(message), 1);
                    }
                }
                if (profiles[targetProfile]["messages"].length == 0) {
                    $("#security-profile-list input#" + targetProfile).prop("disabled", false);
                    $("#security-profile-list label[for=" + targetProfile + "]").removeAttr("title");
                } else {
                    $("#security-profile-list label[for=" + targetProfile + "]").attr("title", profiles[targetProfile]["messages"].join(" "));
                }
                return result;
            }

            function renderConfig(change_software) {
                // Update Server version input w/ latest version in versions[] array when changing software
                var software = $("div#server-list input:radio:checked").val();
                if (change_software === true && typeof versions[software] !== "undefined") {
                    $("#server-version").val(versions[software][versions[software].length-1]);
                }

                var data = {
                    serverVersion: $("#server-version").val(),
                    opensslVersion: $("#openssl-version").val(),
                    hstsEnabled: $("input#hsts-enabled:checkbox:checked").val(),
                    server: software,
                    securityProfile: $("div#security-profile-list input:radio:checked").val()
                };

                var source = $("#" + data.server + "-template").html();
                var template = Handlebars.compile(source);
                data.visibility = "visible";

                // define profile dependent values
                jQuery.extend(data, {
                    sslProtocols: profiles[data.securityProfile]["sslProtocols"][data.server],
                    cipherSuites: profiles[data.securityProfile]["cipherSuites"],
                    maxDHKeySize: profiles[data.securityProfile]["maxDHKeySize"],
                    clientList: profiles[data.securityProfile]["clientList"]
                });

                // define version dependent values
                jQuery.extend(data, getVersionConstrainedDirectives(data));

                // define server dependent values
                data["elbJson"] = "Fetching JSON...";
                if (data.server == "elb") {
                    $.getJSON("blank-elb-cloudformation-template.json")
                    .done( function( elbTemplate ) {
                        var elbMozillaPolicyVersion = "2015-03";
                        var elbPolicyName = "Mozilla-" + data.securityProfile + "-" + elbMozillaPolicyVersion;
                        elbTemplate["Description"] = "Example ELB with Mozilla recommended ciphersuite";
                        elbTemplate["Resources"]["ExampleELB"]["Properties"]["Listeners"][0]["PolicyNames"] = [
                            elbPolicyName
                        ];
                        elbTemplate["Resources"]["ExampleELB"]["Properties"]["Policies"] = [
                            {
                              "PolicyName": elbPolicyName,
                              "PolicyType": "SSLNegotiationPolicyType",
                              "Attributes": $.map( profiles[data.securityProfile]["elbPolicy"], function (n) {
                                  return {"Name": n,"Value":true };
                              })
                            }
                        ];
                        data["elbJson"] = JSON.stringify(elbTemplate, undefined, 4);
                        $("#server-config-text").html(template(data));
                    })
                    .fail( function( elbTemplate) {
                        console.log("JSON fetch failed: " + JSON.stringify(elbTemplate));
                    });
                }

                // clear the dhparam config for server configs not using DHE
                if (!includesDHEcipherSuites(data.cipherSuites)) {
                    data.dhparam = ''
                }

                // catch invalid version profile combinations
                data.securityProfile = toggleProfileAvailability(
                    isOpenSSLSemVer(data.opensslVersion, "<1.0.1") && data.server != "elb",
                    data.securityProfile,
                    "modern",
                    messageTypes.oldOpenSSL);

                data.securityProfile = toggleProfileAvailability(
                    data.server == "apache" && isSemVer(data.serverVersion, "<2.2.23"),
                    data.securityProfile,
                    "modern",
                    messageTypes.oldApache);

                $( "#server-version" ).autocomplete({
                    source: versions[data.server]
                });

                // create a permalink
                jQuery.extend(data, {
                    queryString: $.param({
                        server: data.server + "-" + data.serverVersion,
                        openssl: data.opensslVersion,
                        hsts: data.hstsEnabled ? "yes" : "no",
                        profile: data.securityProfile
                    })
                });

                $("#server-config-text").html(template(data));
            }

            $("ul#security-profile-list li button").click(function() {
                securityProfile = $(this).text();
                renderConfig(false);
            });
            $("input:radio").change(function() {
                renderConfig(true);
            });
            $("input:checkbox, input:text").change(function() {
                renderConfig(false);
            });
            $( "#openssl-version" ).autocomplete({
                source: versions["openssl"]
            });
            loadFromQueryString();
            renderConfig(false);
        });
    </script>

</head>

<body>
<a href="https://www.mozilla.org/" id="tabzilla">mozilla</a>
<div id="wrapper">
    <h1>Mozilla SSL Configuration Generator</h1>
    <div style="width 100px; float:left; padding:1em;">
        <div id="server-list">
            <input type="radio" name="server" id="apache" value="apache">
            <label for="apache">Apache</label>
            <br />
            <input type="radio" name="server" id="nginx" value="nginx">
            <label for="nginx">Nginx</label>
            <br />
            <input type="radio" name="server" id="lighttpd" value="lighttpd">
            <label for="lighttpd">Lighttpd</label>
            <br />
            <input type="radio" name="server" id="haproxy" value="haproxy">
            <label for="haproxy">HAProxy</label>
            <br />
            <input type="radio" name="server" id="elb" value="elb">
            <label for="elb">AWS ELB</label>
            <br />
        </div>
    </div>
    <div style="width 100px; float:left; padding:1em;">

        <div id="security-profile-list">
            <input type="radio" name="security-profile" id="modern" value="modern">
            <label for="modern">Modern</label>
            <br />
            <input type="radio" name="security-profile" id="intermediate" value="intermediate">
            <label for="intermediate">Intermediate</label>
            <br />
            <input type="radio" name="security-profile" id="old" value="old">
            <label for="old">Old</label>
            <br />
        </div>
    </div>
    <div style="width 100px; float:left; padding:1em;">
        <label for="server-version">Server Version</label>
        <input id="server-version" type="text" maxlength="15" />
        <br />
        <label for="openssl-version">OpenSSL Version</label>
        <input id="openssl-version" type="text" maxlength="15" />
        <br />
        <label for="hsts-enabled"><a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security">HSTS</a> Enabled</label>
        <input id="hsts-enabled" type="checkbox" value="true" />
    </div>
    <div style="clear:both;"></div>
    <div id="server-config-text"></div>
    <div>
        <p><br />
        See also:
            <ul>
                <li><a href="https://wiki.mozilla.org/Security/Server_Side_TLS">Mozilla's Server Side TLS Guidelines</a> for more details on these configurations.</li>
                <li><a href="https://github.com/mozilla/tls-observatory">TLS Observatory</a>, <a href="https://github.com/jvehent/cipherscan">Cipherscan</a> and <a href="https://www.ssllabs.com/ssltest/">SSLLabs</a> to test the configuration of live servers</li>
                <li>Report issues and propose improvements to this generator <a href="https://github.com/mozilla/server-side-tls">on GitHub</a></li>
            </ul>
        </p>
    </div>
    <script>
        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
        m=s.getElementsByTagName(o)[0];a.src=g;m.parentNode.insertBefore(a,m)
        })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

        ga('create', 'UA-66267220-1', 'auto');
        ga('send', 'pageview');
    </script>
</div>
</body>

</html>
